//
// Created by 74269 on 2024/7/29.
//

#include <iostream>
#include <vector>
#include <numeric>

#include "SerialManager.h"
#include "serial/serial.h"
#include "spdlog/spdlog.h"
#include "rxcpp/rx.hpp"

using namespace std;

std::string int2Hex(int val) {
    std::stringstream ss;
    ss << "0x";
    // 整数转换为大写的十六进制字符串，且每个字节占用两个字符的宽度
    ss << std::hex << std::uppercase << std::setfill('0') << std::setw(2) << val;
    return ss.str();
}


string join(vector<uint8_t> const &vec, string delim) {
    if (vec.empty()) {
        return string();
    }

    return accumulate(vec.begin() + 1,
                      vec.end(),
                      int2Hex(vec[0]),
                      [](const string &a, uint8_t b) {
                          return a + ", " + int2Hex(b);
                      });
}


serial::Serial dataSerial("/dev/ttyS3", 115200, serial::Timeout::simpleTimeout(30000));

SerialManager::SerialManager() {

}

void SerialManager::enumeratePorts() {
    vector<serial::PortInfo> devices_found = serial::list_ports();

    vector<serial::PortInfo>::iterator iter = devices_found.begin();

    while (iter != devices_found.end()) {
        serial::PortInfo device = *iter++;

        printf("(%s, %s, %s)\n", device.port.c_str(), device.description.c_str(),
               device.hardware_id.c_str());
    }
}

void SerialManager::action(vector<uint8_t> instruct) {


    spdlog::info("send    -> {}", join(instruct, ", "));
    dataSerial.write(instruct);

    std::vector<uint8_t> result;
    auto                 b = dataSerial.waitReadable();
    auto bufferSize = dataSerial.available();
    auto size = dataSerial.read(result, bufferSize);

    spdlog::info("receive -> {}", join(result, ", "));

//    for (vector<uint8_t>::iterator it = result.begin(); it != result.end(); ++it) {
//        spdlog::info("data -> {:#04X}", *it);
//    }


//    rxcpp::observable<>::create<int>([](const rxcpp::subscriber<int> &subscriber) {
//        spdlog::info("create3... ");
//
//
//        subscriber.on_next(1);
//    })
//            .subscribe_on(rxcpp::observe_on_new_thread())
//            .observe_on(rxcpp::observe_on_new_thread())
//            .subscribe([](int i) {
//                           spdlog::info("subscribe ...");
//                       }
//            );
}

SerialManager::~SerialManager() {

}
